/**
 * File: SequenceQualityType.java
 * Created by: mhaimel
 * Created on: Jun 16, 2010
 * CVS:  $Id: SequenceQualityType.java 1.0 Jun 16, 2010 4:25:22 PM mhaimel Exp $
 */
package uk.ac.ebi.curtain.utils.file;


/**
 * @author mhaimel
 *
 */
public enum SequenceQualityType {
	
	Sanger(33,0,93),
	Illumina(64,2,40);

	private final int offset;
	private final int min;
	private final int max;

	private SequenceQualityType(int offset,int min,int max){
		this.offset= offset;
		this.min=min;
		this.max=max;
	}
	
	public boolean inRange(char c){
		return inRange(toQuality(c));
	}	
	
	public boolean inRange(byte val){
		return inRange((int)val);
	}
	
	public boolean inRange(int val){
		if(min > val){
			return false;
		}
		if(max < val){
			return false;
		}
		return true;
	}
	
	public int toQuality(char c){
		return ((int)c)-offset;
	}
	
	public char toChar(int val){
		return (char)(val+offset);
	}
	
	public int getOffset() {
		return offset;
	}
	public int getMin(){
		return min;
	}
	public int getMax(){
		return max;
	}
	
	public String fromQuality(byte[] qual) {
		StringBuilder sb = new StringBuilder();
		int len = qual.length;
		for(int i = 0; i < len; ++i){
			byte val = qual[i];
			char c = toChar(val);
			if(!inRange((int)val)) {
				if(val < getMin()){
					c = toChar(getMin());
				} else if(val > getMax()){
					c = toChar(getMax());
				}
			}	
			sb.append(c);
		}
		return sb.toString();
	}
	
	public byte[] toQuality(String quality) throws IllegalArgumentException {
		return toQuality(quality, true);
	}
	
	public byte[] toQuality(String quality, boolean fail) throws IllegalArgumentException {
		int len = quality.length();
		byte[] qual = new byte[len];
		for(int i = 0; i < len; ++i){
			char c = quality.charAt(i);
			int q = toQuality(c);
			if(!inRange(q)) {
				if(fail){
					throw new IllegalArgumentException("Value out of range for type " + this + ":" + c + "=>"+q+"< ?" );
				} else {
					if(q < getMin()){
						q = getMin();
					} else if(q > getMax()){
						q = getMax();
					}
				}
			}	
			qual[i] = (byte) q;
		}
		return qual;
	}
	
}
